﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using BlockeyEssentials.ScreenSystem;

namespace BlockeyEssentials
{
    public static class All
    {

        #region Fields

        //const int View_Width = 1280;
        //const int View_Height = 720;
        private static int View_Width;
        private static int View_Height;
        private static Rectangle m_oResolution = new Rectangle(0, 0, View_Width, View_Height);
        private static Vector2 m_oCenter = new Vector2(View_Width, View_Height) * 0.5f;

        public static GraphicsDeviceManager Graphics;
        public static SpriteBatch SpriteBatch_Debug;
        public static GameTime GameTime;
        public static SpriteFont Font_Debug;
        public static Texture2D Texture_Circle;
        public static Texture2D Texture_Square;
        public static Texture2D Texture_Rainbow;
        public static Texture2D Texture_PersonTemplate;
        public static Texture2D Texture_PersonTestHome;
        public static Texture2D Texture_PersonTestAway;
        public static Texture2D Texture_PersonTestNeutral;

        private static ScreenManager _CurrentManager;


        #endregion

        #region Properties

        /// <summary>
        /// The Width and Height of the Viewing Resolution
        /// </summary>
        public static Rectangle Resolution
        {
            get { return m_oResolution; }
        }

        public static Vector2 Center
        {
            get { return m_oCenter; }
        }

        public static ScreenManager CurrentScreenManager
        {
            get { return _CurrentManager; }
            set { _CurrentManager = value; }
        }

        public static ScreenManager DestinationScreenManager
        {
            get;
            set;
        }

        public static bool Just3DTest
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Loads the basics Graphics and Fonts used Globally throughout the program
        /// </summary>
        /// <param name="oContent">The Content Manager of the Game</param>
        public static void StartGraphicSettings(Game oGame)
        {
            All.Graphics = new GraphicsDeviceManager(oGame);

            View_Width = 1280;
            View_Height = 720;

            m_oResolution = new Rectangle(0, 0, View_Width, View_Height);
            m_oCenter = new Vector2(View_Width, View_Height) * 0.5f;

            All.Graphics.PreferredBackBufferWidth = All.Resolution.Width;
            All.Graphics.PreferredBackBufferHeight = All.Resolution.Height;
            oGame.Content.RootDirectory = "Content";
        }

        public static void LoadEssentials(Game oGame)
        {
            //// -- Fonts -- ////
            All.Font_Debug = oGame.Content.Load<SpriteFont>("Essentials\\Debug");

            //// -- Textures -- ////
            All.Texture_Circle = oGame.Content.Load<Texture2D>("Essentials\\Circle");
            All.Texture_Square = oGame.Content.Load<Texture2D>("Essentials\\Square");
            All.Texture_Rainbow = oGame.Content.Load<Texture2D>("Essentials\\Rainbow");
            All.Texture_PersonTemplate = oGame.Content.Load<Texture2D>("PersonTemplate");
            All.Texture_PersonTestHome = oGame.Content.Load<Texture2D>("PersonTestHome");
            All.Texture_PersonTestAway = oGame.Content.Load<Texture2D>("PersonTestAway");
            All.Texture_PersonTestNeutral = oGame.Content.Load<Texture2D>("PersonTestNeutral");

            //// -- SpriteBatches -- ////
            All.SpriteBatch_Debug = new SpriteBatch(oGame.GraphicsDevice);
        }

        // Draws a line of Debug Text
        public static void DrawDebugText(string oText, Vector2 oPosition, bool oDrawBG)
        {
            Vector2 oMeasure = Font_Debug.MeasureString(oText);

            if (oDrawBG)
            {
                SpriteBatch_Debug.Draw(Texture_Square,
                    new Rectangle((int)oPosition.X, (int)oPosition.Y, (int)oMeasure.X, (int)oMeasure.Y),
                    null, Color.Black, 0.0f, Vector2.Zero, SpriteEffects.None, 0.0f);
            }

            SpriteBatch_Debug.DrawString(
                Font_Debug, oText, oPosition, Color.White,
                0.0f, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
        }

        #endregion

        #region Helper Methods

        /// <summary>
        /// Changes an angle in radians to a Vector2
        /// </summary>
        /// <param name="angle">Angle in Radians</param>
        /// <returns>Vector2 in the direction of the angle</returns>
        public static Vector2 AngleToVector(float angle)
        {
            return new Vector2((float)Math.Sin(angle), -(float)Math.Cos(angle));
        }

        /// <summary>
        /// Changes a Vector into an Angle in Radians
        /// </summary>
        /// <param name="vector">Vector in some direction</param>
        /// <returns>The Angle in Radians</returns>
        public static float VectorToAngle(Vector2 vector)
        {
            return (float)Math.Atan2(vector.Y, vector.X);
        }

        public static float AngleBetweenVectors(Vector2 a, Vector2 b)
        {
            var top = ((a.X * b.X) + (a.Y * b.Y));
            var bottom = (Math.Sqrt((a.X * a.X) + (a.Y * a.Y)) * Math.Sqrt((b.X * b.X) + (b.Y * b.Y)));
            var angle = (float)Math.Acos(top / bottom);

            return angle;
        }

        public static Vector2 CenterOfImage(Texture2D oTexture)
        {
            return new Vector2(oTexture.Width, oTexture.Height) * 0.5f;
        }

        #endregion

        private static bool IsDebugStarted = false;

    }
}
